package jpave.query_interface;

/****************************************************
 * Blast tab - runs blast and displays results
 */
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.sql.Connection;

import javax.swing.*;
import javax.swing.JLabel;
import javax.swing.border.Border;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import assem.Utils;
import util.Debug.ErrorReport;
import util.methods.BlastArgs;
import util.ui.UserPrompt;

import java.sql.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import jpave.dataholders.SessionData;
import jpave.manager.ManagerFrame;
import util.ui.TableColumnSizer;

public class BlastTab extends Tab
{
	private static final long serialVersionUID = 653192706293635582L;
	JPaveFrame theParentFrame = null;
	SessionData theSession = null;
	JTextArea inputSeq = null;
	JCheckBox tabCheck = null;
	JCheckBox nontabCheck = null;
	ButtonGroup outType = null;
	JCheckBox nucCheck = null;
	JCheckBox protCheck = null;
	ButtonGroup seqType = null;
	FileTextField inputBlastPath = null;
	JPanel blastPathPanel = null;
	JTable resultTable = null;

	JTextField inputEval = null;
	JPanel resultSection = null;
	JPanel pnlRealMain = null;
	File outFile = null;
	final JButton btnViewContig; // have to do this to use in action handler
	static File baseDir = null;
	
	public BlastTab(JPaveFrame parentFrame) 
	{
		super(parentFrame, null);
		setBackground(Color.white);
		theParentFrame = parentFrame;
		theSession = theParentFrame.getAssemblyList();
		
        JButton btnHelp = new JButton("Help");
        btnHelp.setBackground(ManagerFrame.HELPCOLOR);
        btnHelp.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				UserPrompt.displayHTMLResourceHelp(theParentFrame, "Blast Help", "html/viewSingleTCW/BlastTab.html");
			}
		});

		btnViewContig = new JButton("View Selected Sequence");
		btnViewContig.setBackground(ManagerFrame.FUNCTIONCOLOR);
		btnViewContig.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent event) {
				if (resultTable.getSelectedRowCount() == 1)
					addContigTab();
				
			}
		});
		btnViewContig.setEnabled( false );
		
		JPanel row = null;		
		row = new JPanel();
		row.setLayout(new BoxLayout(row, BoxLayout.LINE_AXIS));
		row.setBackground(Color.white);		
		row.setAlignmentX(LEFT_ALIGNMENT);

		pnlRealMain = new JPanel();
		pnlRealMain.setLayout(new BoxLayout(pnlRealMain, BoxLayout.PAGE_AXIS));
		pnlRealMain.setBackground(Color.white);
		pnlRealMain.setAlignmentX(LEFT_ALIGNMENT);
		pnlRealMain.setBorder(null);
		JLabel lblBlast = new JLabel("Blast Sequences");
		lblBlast.setFont(new Font("Verdana",Font.PLAIN,18));
		row.add(lblBlast);
		row.add(Box.createHorizontalStrut(150));
		row.add(btnHelp);
		row.add(Box.createHorizontalGlue());
		pnlRealMain.add(row);
		pnlRealMain.add(Box.createVerticalStrut(15));
		
		JPanel pnlMain = new JPanel();
		pnlMain.setLayout(new BoxLayout(pnlMain, BoxLayout.PAGE_AXIS));
		pnlMain.setBackground(Color.white);
		pnlMain.setAlignmentX(LEFT_ALIGNMENT);
		pnlMain.setBorder(null);
				
		row = new JPanel();
		row.setLayout(new BoxLayout(row, BoxLayout.LINE_AXIS));
		row.setBackground(Color.white);		
		row.setAlignmentX(LEFT_ALIGNMENT);
		row.add(new JLabel("Sequence(s) to blast -- amino acid or nucleotide (single sequence or FASTA format)"));
		row.add(new JLabel(""));
		pnlMain.add(row);
		pnlMain.add(Box.createVerticalStrut(2));

		row = new JPanel();
		row.setLayout(new BoxLayout(row, BoxLayout.LINE_AXIS));
		row.setBackground(Color.white);	
		row.setAlignmentX(LEFT_ALIGNMENT);
		inputSeq = new JTextArea(5,40);
		inputSeq.setMinimumSize(inputSeq.getPreferredSize());
		JScrollPane sp = new JScrollPane(inputSeq);
		Border border = BorderFactory.createLineBorder(Color.BLACK);
		inputSeq.setBorder(border);
		inputSeq.setEditable(true);
		inputSeq.setFont(new Font("Verdana", Font.PLAIN, 14));
		inputSeq.setLineWrap(true);
		
		row.add(sp);
		row.add(Box.createHorizontalGlue());
		pnlMain.add(row);
		pnlMain.add(Box.createVerticalStrut(10));
		
		row = new JPanel();
		row.setLayout(new BoxLayout(row, BoxLayout.LINE_AXIS));
		row.setBackground(Color.white);		
		row.setAlignmentX(LEFT_ALIGNMENT);
		row.add(new JLabel("E-value: "));
		inputEval = new JTextField("1E-10  ");
		inputEval.setMaximumSize(inputEval.getPreferredSize());
		row.add(inputEval);
		row.add(Box.createHorizontalGlue());
		row.add(Box.createHorizontalGlue());
		pnlMain.add(row);
		pnlMain.add(Box.createVerticalStrut(10));
	
		tabCheck = new JCheckBox();
		nontabCheck = new JCheckBox();
		outType = new ButtonGroup();
		outType.add(tabCheck);
		outType.add(nontabCheck);
		tabCheck.setSelected(true);
		row = new JPanel();
		row.setLayout(new BoxLayout(row, BoxLayout.LINE_AXIS));
		row.setBackground(Color.white);		
		row.setAlignmentX(LEFT_ALIGNMENT);
		row.add(new JLabel("Output format: "));
		row.add(tabCheck);
		row.add(new JLabel(" tabular  "));
		row.add(nontabCheck);
		row.add(new JLabel(" long"));
		row.add(Box.createHorizontalGlue());
		pnlMain.add(row);
		pnlMain.add(Box.createVerticalStrut(10));

		row = new JPanel();
		row.setLayout(new BoxLayout(row, BoxLayout.LINE_AXIS));
		row.setBackground(Color.white);		
		row.setAlignmentX(LEFT_ALIGNMENT);
		JButton btnBlast = new JButton("Run Blast");
		btnBlast.setBackground(ManagerFrame.FUNCTIONCOLOR);
		btnBlast.addActionListener(
					new ActionListener() 
					{
						public void actionPerformed(ActionEvent event) 
						{
							Thread theThread = new Thread(new Runnable() {
								public void run() 
								{
							    	try 
							    	{
							    		runBlast();
							    	}
							    	catch(Exception e) 
							    	{
							    		e.printStackTrace();
							    	}
								}
							});
							theThread.start();
						}
					}
				);
		row.add(btnBlast);
		row.add(Box.createHorizontalGlue());
		pnlMain.add(row);
		pnlMain.add(Box.createVerticalStrut(10));
		
		inputBlastPath = new FileTextField(30);
		if (!BlastArgs.foundABlast())
		{
			blastPathPanel = new JPanel();
			blastPathPanel.setLayout(new BoxLayout(blastPathPanel, BoxLayout.PAGE_AXIS));
			blastPathPanel.setBackground(Color.white);		
			blastPathPanel.setAlignmentX(LEFT_ALIGNMENT);

			row = new JPanel();
			row.setLayout(new BoxLayout(row, BoxLayout.LINE_AXIS));
			row.setBackground(Color.white);		
			row.setAlignmentX(LEFT_ALIGNMENT);
			row.add(new JLabel("BLAST program directory: "));
			row.add(inputBlastPath);
			blastPathPanel.add(row);
			blastPathPanel.add(Box.createVerticalStrut(10));
			pnlMain.add(blastPathPanel);
		}

		pnlRealMain.add(pnlMain);
		
		resultSection = new JPanel();
		resultSection.setLayout(new BoxLayout(resultSection, BoxLayout.PAGE_AXIS));
		resultSection.setAlignmentX(Box.LEFT_ALIGNMENT);
		resultSection.setBackground(Color.white);		
		resultSection.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
		pnlRealMain.add(resultSection);
		pnlRealMain.add(Box.createVerticalGlue());
		add(pnlRealMain);
	}
	/****************************************************************
	 * runBLAST
	 */
	void runBlast() throws Exception
	{		
		if (!BlastArgs.foundABlast())
		{
			String bpath = inputBlastPath.getText().trim();
			if (bpath.equals(""))
			{
				JOptionPane.showMessageDialog(theParentFrame, 
						"Please enter the location of the BLAST programs", "", 
						JOptionPane.OK_OPTION);
				return;
			}
			BlastArgs.evalBlastPath(bpath, "", "");
			if (!BlastArgs.foundABlast())
			{
				JOptionPane.showMessageDialog(theParentFrame, 
						"The BLAST programs were not found at:\n" + bpath, "", 
						JOptionPane.OK_OPTION);
				return;
			}
		}
		if (blastPathPanel != null)
		{
			blastPathPanel.removeAll();
		}
		resultSection.removeAll();
		pnlRealMain.revalidate();
		resultTable = null;

		if (!util.methods.UIHelpers.isApplet())
		{
			baseDir = new File("blast/");
			if(!baseDir.exists())
				baseDir.mkdir();
		}
		else
		{
			// applet - use a tmp dir but try to use the same one instead of constantly dumping
			// seq files into new dirs
			if (baseDir ==  null || !baseDir.isDirectory())
			{
				// goal here is to find the tmp dir and then use our own file name
				baseDir = File.createTempFile("tcw_blast", ""); 
				baseDir.delete();
				String path = baseDir.getAbsolutePath();
				Pattern p = Pattern.compile("(.*tcw_blast).*");
				Matcher m = p.matcher(path);
				if (m.matches())
				{
					path = m.group(1);
					baseDir = new File(path);
					if (baseDir.isDirectory())
					{
						Utils.deleteDir(baseDir);
					}
				}
				baseDir.mkdir();
			}
		}

		String ID = theSession.getID();
		File seqFile = new File(baseDir,ID + ".seq");
		boolean haveFile = false;
		if (seqFile.isFile())
		{
			haveFile = true;
		}
		
		Connection c = theSession.getConnection();
		Statement s = c.createStatement();
		ResultSet r = null;
		boolean dbProt = false;
		r = s.executeQuery("show columns from assem_msg like 'peptide'");
		if (r.first())
		{
			dbProt = true;
		}
		
		if (!haveFile)
		{
			r = s.executeQuery("select count(*) from contig");
			r.first();
			int nclones = r.getInt(1);			
			System.err.println("writing target database of " + nclones + "  sequences");
			
			seqFile.createNewFile();
			BufferedWriter w = new BufferedWriter(new FileWriter(seqFile));
			
			r = s.executeQuery("select contigid, consensus from contig");
			while (r.next())
			{
				String name = r.getString(1);
				String seq = r.getString(2);
				w.write(">" + name);
				w.newLine();
				w.write(seq);
				w.newLine();
			}			
			w.close();
		}
		boolean tabular = tabCheck.isSelected();
		String eVal = inputEval.getText();

		boolean seqProt = true;
		String wholeSeq = inputSeq.getText().trim();
		// First, find a sequence line and see if it's nucleotide
		if (wholeSeq.startsWith(">"))
		{
			String[] seqs = wholeSeq.split("\\n");
			if (seqs.length > 1)
			{
				if (BlastArgs.isNucleotide(seqs[1])) {
					seqProt = false;
					System.out.println("Query is nucleotide sequence");
				}
				else if (BlastArgs.isProtein(seqs[1])) // CAS 4July15 was isNucleotide
						System.out.println("Query is protein sequence");		
				else System.out.println("Sequence type is ambiguous -- try protein search");
			}
			else
			{
				errOut("Invalid sequence entered");
				return;
			}
		}
		else
		{
			// this means it must be all sequence and we will need to add a header
			if (BlastArgs.isNucleotide(wholeSeq)) {
				seqProt = false;
				System.out.println("Query is nucleotide sequence");
			}
			else if (BlastArgs.isProtein(wholeSeq))
					System.out.println("Query is protein sequence");		
			else System.out.println("Sequence type is ambiguous -- try protein search");
			wholeSeq = ">query\n" + wholeSeq;
		}
		
		File queryFile = new File(baseDir,ID+".query.seq");
		if (queryFile.exists()) queryFile.delete();
		queryFile.createNewFile();
		BufferedWriter w = new BufferedWriter(new FileWriter(queryFile));
		w.write(wholeSeq); w.newLine();
		w.close();

		boolean formatDone = false;
		if (dbProt)
		{
			File phr = (new File(seqFile.getAbsolutePath() + ".phr"));
			File pin = (new File(seqFile.getAbsolutePath() + ".pin"));
			File psq = (new File(seqFile.getAbsolutePath() + ".psq"));
							
			if(haveFile && phr.exists() && pin.exists() && psq.exists()) 
			{
				formatDone = true;
			}
		}
		else
		{
			File nhr = (new File(seqFile.getAbsolutePath() + ".nhr"));
			File nin = (new File(seqFile.getAbsolutePath() + ".nin"));
			File nsq = (new File(seqFile.getAbsolutePath() + ".nsq"));
							
			if(haveFile && nhr.exists() && nin.exists() && nsq.exists()) 
			{
				formatDone = true;
			}			
		}

		if(!formatDone) 
		{
			if (!BlastArgs.isBlastPlus()) 
			{
				String prot = (dbProt ? " -pT " : " -pF ");
				System.err.println("Executing: " + "formatdb " + prot + " -i " + seqFile.getAbsolutePath());
				Process pFormatDB = Runtime.getRuntime().exec("formatdb " + prot + " -i " + seqFile.getAbsolutePath());
				pFormatDB.waitFor();
			}
			else 
			{
				String cmd = (dbProt ? BlastArgs.getFormatp(seqFile.getAbsolutePath()) : 
						BlastArgs.getFormatn(seqFile.getAbsolutePath()));
				System.err.println("Executing: " + cmd);
				Process pFormatDB = Runtime.getRuntime().exec(cmd);
				pFormatDB.waitFor();

			}
		}
		
		outFile = new File(baseDir.getAbsolutePath() + "/" + ID + ".result.txt");
		String blastCmd ;
		if (dbProt)
		{
			if (seqProt)
			{
				//blastp
				blastCmd = BlastArgs.buildBlastCommand(queryFile.getAbsolutePath(),seqFile.getAbsolutePath(), 
						outFile.getAbsolutePath(), "blastp",1,eVal,tabular,"" );
			}
			else
			{
				//blastx
				blastCmd = BlastArgs.buildBlastCommand(queryFile.getAbsolutePath(),seqFile.getAbsolutePath(), 
						outFile.getAbsolutePath(), "blastx",1,eVal,tabular,"" );
			}	
		}
		else
		{
			if (seqProt)
			{
				if (!BlastArgs.isBlastPlus())
				{
					errOut("Unable to blast protein vs. nucleotide using legacy Blast.\nPlease install blast+ and update your HOSTS.cfg.");
					return;
				}
				//tblastn
				blastCmd = BlastArgs.buildBlastCommand(queryFile.getAbsolutePath(),seqFile.getAbsolutePath(), 
						outFile.getAbsolutePath(), "tblastn",1,eVal,tabular,"" );
			}
			else
			{
				//blastn
				blastCmd = BlastArgs.buildBlastCommand(queryFile.getAbsolutePath(),seqFile.getAbsolutePath(), 
						outFile.getAbsolutePath(), "blastn",1,eVal,tabular,"" );
			}			
		}
	// Execution
		if (blastCmd.equals("")) return;
		System.err.println("Executing: " + blastCmd);
		Process p = Runtime.getRuntime().exec(blastCmd);
		p.waitFor();
		System.err.println("blast completed");
		
		if (!outFile.isFile()) {
			errOut("No results were found");
			return;

		}
		
		int nrows = 0;
		BufferedReader br = new BufferedReader(new FileReader(outFile));
		while (br.ready())
		{
			if (!br.readLine().trim().equals(""))
			{
				nrows++;
				break;
			}
		}
		br.close();
		if (nrows == 0)
		{
			errOut("No results were found");
			return;
		}	
		
		if (tabular)
		{
			nrows = 0;
			int ncols = 0;
			br = new BufferedReader(new FileReader(outFile));
			while (br.ready())
			{
				String line = br.readLine();
				if (ncols == 0)
				{
					ncols = line.split("\\s+").length;
				}
				nrows++;
			}
			br.close();
			br = new BufferedReader(new FileReader(outFile));
			String[][] data = new String[nrows][ncols];
			nrows = 0;
			while (br.ready())
			{
				data[nrows] = br.readLine().split("\\s+");
				nrows++;
			}
			String[] colNames = new String[ncols];
			for (int i = 0; i < ncols; i++) colNames[i]="";
			if (ncols == 12) // it should
			{
				colNames[0] = "Query";
				colNames[1] = "Subject";
				colNames[2] = "% id";
				colNames[3] = "align len";
				colNames[4] = "mismatch";
				colNames[5] = "gaps";
				colNames[6] = "q.start";
				colNames[7] = "q.end";
				colNames[8] = "s.start";
				colNames[9] = "s.end";
				colNames[10] = "e-value";
				colNames[11] = "bit score";
			}
			resultTable = new JTable(data,colNames);
			resultTable.setBorder(BorderFactory.createLineBorder(Color.black));
			TableColumnSizer.resizeColumns(resultTable);

			JScrollPane sPane = new JScrollPane(resultTable); 
			int tHeight = resultTable.getPreferredSize().height;
			int tWidth = resultTable.getPreferredSize().width;
			Dimension scrollDim = new Dimension(Math.min(tWidth+50,900),Math.min(tHeight+50, 450));
			sPane.setPreferredSize(scrollDim);
			sPane.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
			resultSection.add(sPane);
			resultSection.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
			
			resultTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() 
			{
				public void valueChanged(ListSelectionEvent event) 
				{
					btnViewContig.setEnabled( resultTable.getSelectedRowCount() == 1 );
				}
			});
		}
		else
		{
			StringBuffer sb = new StringBuffer();
			br = new BufferedReader(new FileReader(outFile));
			while (br.ready())
			{
				// CAS 4July15 removed trim() has mess-up indentation
				sb.append(br.readLine() + "\n");
			}
			br.close();
			JTextArea messageArea = new JTextArea(25,40);

			JScrollPane sPane = new JScrollPane(messageArea); 
			Dimension scrollDim = new Dimension(625,400);
			sPane.setPreferredSize(scrollDim);

			messageArea.setFont(new Font("monospaced", Font.BOLD, 12));
			messageArea.setEditable(false);
			messageArea.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
			messageArea.setMaximumSize(messageArea.getPreferredSize());
			messageArea.setText(sb.toString());
			resultSection.add(sPane);
		}
		resultSection.add(Box.createVerticalStrut(5));
		
		JButton btnSave = new JButton("Export"); // CAS 11/26/14 - consistency
		btnSave.setBackground(ManagerFrame.FUNCTIONCOLOR);
		btnSave.addActionListener(
			new ActionListener() 
			{
				public void actionPerformed(ActionEvent event) 
				{
					doSave();
				}
			}
		);	

		JPanel row = new JPanel();
		row.setLayout(new BoxLayout(row, BoxLayout.LINE_AXIS));
		row.setBackground(Color.white);		
		row.setAlignmentX(LEFT_ALIGNMENT);
		row.add(btnSave);
		if (tabular)
		{
			row.add(Box.createHorizontalStrut(10));
			row.add(btnViewContig);
		}
		resultSection.add(row);
		resultSection.add(Box.createVerticalGlue());
		
		pnlRealMain.revalidate();
	}
	private void errOut(String err)
	{
		System.err.println(err);
		resultSection.add(new JLabel(err));
		resultSection.revalidate();
	}
	private void deleteFiles(File seqFile)
	{
		File phr = (new File(seqFile.getAbsolutePath() + ".phr"));
		File pin = (new File(seqFile.getAbsolutePath() + ".pin"));
		File psq = (new File(seqFile.getAbsolutePath() + ".psq"));
		File nhr = (new File(seqFile.getAbsolutePath() + ".nhr"));
		File nin = (new File(seqFile.getAbsolutePath() + ".nin"));
		File nsq = (new File(seqFile.getAbsolutePath() + ".nsq"));	
		if (seqFile.isFile()) seqFile.delete();
		if (phr.isFile()) phr.delete();
		if (pin.isFile()) pin.delete();
		if (psq.isFile()) psq.delete();
		if (nhr.isFile()) nhr.delete();
		if (nin.isFile()) nin.delete();
		if (nsq.isFile()) nsq.delete();
	}
	
	private void doSave() 
	{
		try
		{
			if (outFile == null || !outFile.isFile())
			{
				System.err.println("The output file " + outFile.getAbsolutePath() + " does not exist");
				return;
			}
			final JFileChooser fc = new JFileChooser(theParentFrame.lastSaveFilePath);
			fc.setSelectedFile(new File("blast.csv")); // CAS 12/26/14 
			
			if (fc.showSaveDialog(theParentFrame) == JFileChooser.APPROVE_OPTION) 
			{
				File f = fc.getSelectedFile();
				int writeOption = JOptionPane.YES_OPTION;
				if (f.exists()) 
				{
					writeOption = JOptionPane.showConfirmDialog(
						    theParentFrame,
						    "The file already exists, overwrite it?",
						    "Save to File",
						    JOptionPane.YES_NO_OPTION);
				}
				if (writeOption == JOptionPane.YES_OPTION) 
				{
					f.delete();
				}
				else
				{
					return;
				}
				if (f.createNewFile())
				{
					theParentFrame.setLastPath(f.getPath()); // CAS 12/26/14
					System.err.println("Write file " + f.getPath());
					BufferedReader r = new BufferedReader(new FileReader(outFile));
					BufferedWriter w = new BufferedWriter(new FileWriter(f));
					int num = 0;
					while (r.ready())
					{
						w.write(r.readLine()); w.newLine(); num++;
					}
					r.close(); w.close();
					System.err.println("   wrote " + num + " lines");
				}
				else
				{
					System.err.println("Could not create file " + f.getAbsolutePath());
				}
			}
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
	}
	private void addContigTab ( )
	{
		if (resultTable != null)
		{
			int nRow = resultTable.getSelectedRow();
			
			if (nRow < 0)return;
			
			String strName = resultTable.getValueAt(nRow, 1).toString();
			theParentFrame.addContigPage(strName, this, nRow, JPaveFrame.ShowAllContigs);
		}
	}
	
	private class FileTextField extends JPanel {
		private static final long serialVersionUID = 2509867678940815100L;
		public FileTextField(int size) {
			setLayout(new BoxLayout(this, BoxLayout.LINE_AXIS));
			setAlignmentX(Component.LEFT_ALIGNMENT);
			setBackground(ManagerFrame.BGCOLOR);
			
			txtValue = new JTextField(size);
			Dimension dTxt = txtValue.getPreferredSize(); 
			txtValue.setMaximumSize(dTxt);
			txtValue.setMinimumSize(dTxt);
			
			btnFindFile = new JButton("...");
			btnFindFile.setBackground(ManagerFrame.BGCOLOR);
			Dimension dBtn = new Dimension();
			dBtn.width = btnFindFile.getPreferredSize().width;
			dBtn.height = dTxt.height;
			
			btnFindFile.setMaximumSize(dBtn);
			btnFindFile.setMinimumSize(dBtn);
			btnFindFile.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent arg0) {
					try {
						JFileChooser fc = new JFileChooser();
						fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);

						if(fc.showOpenDialog(theParentFrame) == JFileChooser.APPROVE_OPTION) {
							txtValue.setText(fc.getSelectedFile().getPath());
						}
					}
					catch(Exception e) {
						ErrorReport.prtReport(e, "Error finding file");
					}
					
				}});
			
			add(txtValue);
			add(btnFindFile);
		}
		
		public void setEnabled(boolean enabled) { 
			txtValue.setEnabled(enabled);
			btnFindFile.setEnabled(enabled);
		}
		
		public void setText(String text) { txtValue.setText(text); }
		public String getText() { return txtValue.getText(); }
		
		private JTextField txtValue = null;
		private JButton btnFindFile = null;
	}
}
